{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/AI4Finance-Foundation/FinRL/blob/master/FinRL_StockTrading_NeurIPS_2018.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gXaoZs2lh1hi"
      },
      "source": [
        "# Deep Reinforcement Learning for Stock Trading from Scratch: Multiple Stock Trading\n",
        "\n",
        "* **Pytorch Version** \n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lGunVt8oLCVS"
      },
      "source": [
        "# Content"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HOzAKQ-SLGX6"
      },
      "source": [
        "* [1. Problem Definition](#0)\n",
        "* [2. Getting Started - Load Python packages](#1)\n",
        "    * [2.1. Install Packages](#1.1)    \n",
        "    * [2.2. Check Additional Packages](#1.2)\n",
        "    * [2.3. Import Packages](#1.3)\n",
        "    * [2.4. Create Folders](#1.4)\n",
        "* [3. Download Data](#2)\n",
        "* [4. Preprocess Data](#3)        \n",
        "    * [4.1. Technical Indicators](#3.1)\n",
        "    * [4.2. Perform Feature Engineering](#3.2)\n",
        "* [5.Build Environment](#4)  \n",
        "    * [5.1. Training & Trade Data Split](#4.1)\n",
        "    * [5.2. User-defined Environment](#4.2)   \n",
        "    * [5.3. Initialize Environment](#4.3)    \n",
        "* [6.Implement DRL Algorithms](#5)  \n",
        "* [7.Backtesting Performance](#6)  \n",
        "    * [7.1. BackTestStats](#6.1)\n",
        "    * [7.2. BackTestPlot](#6.2)   \n",
        "    * [7.3. Baseline Stats](#6.3)   \n",
        "    * [7.3. Compare to Stock Market Index](#6.4)   \n",
        "* [RLlib Section](#7)            "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sApkDlD9LIZv"
      },
      "source": [
        "<a id='0'></a>\n",
        "# Part 1. Problem Definition"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HjLD2TZSLKZ-"
      },
      "source": [
        "This problem is to design an automated trading solution for single stock trading. We model the stock trading process as a Markov Decision Process (MDP). We then formulate our trading goal as a maximization problem.\n",
        "\n",
        "The algorithm is trained using Deep Reinforcement Learning (DRL) algorithms and the components of the reinforcement learning environment are:\n",
        "\n",
        "\n",
        "* Action: The action space describes the allowed actions that the agent interacts with the\n",
        "environment. Normally, a ∈ A includes three actions: a ∈ {−1, 0, 1}, where −1, 0, 1 represent\n",
        "selling, holding, and buying one stock. Also, an action can be carried upon multiple shares. We use\n",
        "an action space {−k, ..., −1, 0, 1, ..., k}, where k denotes the number of shares. For example, \"Buy\n",
        "10 shares of AAPL\" or \"Sell 10 shares of AAPL\" are 10 or −10, respectively\n",
        "\n",
        "* Reward function: r(s, a, s′) is the incentive mechanism for an agent to learn a better action. The change of the portfolio value when action a is taken at state s and arriving at new state s',  i.e., r(s, a, s′) = v′ − v, where v′ and v represent the portfolio\n",
        "values at state s′ and s, respectively\n",
        "\n",
        "* State: The state space describes the observations that the agent receives from the environment. Just as a human trader needs to analyze various information before executing a trade, so\n",
        "our trading agent observes many different features to better learn in an interactive environment.\n",
        "\n",
        "* Environment: Dow 30 consituents\n",
        "\n",
        "\n",
        "The data of the single stock that we will be using for this case study is obtained from Yahoo Finance API. The data contains Open-High-Low-Close price and volume.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ffsre789LY08"
      },
      "source": [
        "<a id='1'></a>\n",
        "# Part 2. Getting Started- Load Python Packages"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Uy5_PTmOh1hj"
      },
      "source": [
        "<a id='1.1'></a>\n",
        "## 2.1. Install all the packages through FinRL library\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mPT0ipYE28wL",
        "outputId": "ef0ba8d0-f57a-4c74-bb0b-46737762677d"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Collecting git+https://github.com/AI4Finance-LLC/FinRL-Library.git\n",
            "  Cloning https://github.com/AI4Finance-LLC/FinRL-Library.git to /tmp/pip-req-build-8i1_yu6g\n",
            "  Running command git clone -q https://github.com/AI4Finance-LLC/FinRL-Library.git /tmp/pip-req-build-8i1_yu6g\n",
            "Collecting pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2\n",
            "  Cloning https://github.com/quantopian/pyfolio.git to /tmp/pip-install-5a06fizc/pyfolio_a7217f0bb5e740febfbf6fb40b942785\n",
            "  Running command git clone -q https://github.com/quantopian/pyfolio.git /tmp/pip-install-5a06fizc/pyfolio_a7217f0bb5e740febfbf6fb40b942785\n",
            "Collecting elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl\n",
            "  Cloning https://github.com/AI4Finance-Foundation/ElegantRL.git to /tmp/pip-install-5a06fizc/elegantrl_2c9dffb258c6419bb2f5c6a8409b99b2\n",
            "  Running command git clone -q https://github.com/AI4Finance-Foundation/ElegantRL.git /tmp/pip-install-5a06fizc/elegantrl_2c9dffb258c6419bb2f5c6a8409b99b2\n",
            "Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (1.19.5)\n",
            "Requirement already satisfied: pandas>=1.1.5 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (1.1.5)\n",
            "Collecting stockstats\n",
            "  Downloading stockstats-0.3.2-py2.py3-none-any.whl (13 kB)\n",
            "Collecting yfinance\n",
            "  Downloading yfinance-0.1.67-py2.py3-none-any.whl (25 kB)\n",
            "Collecting elegantrl\n",
            "  Downloading elegantrl-0.3.2-py3-none-any.whl (73 kB)\n",
            "\u001b[K     |████████████████████████████████| 73 kB 2.0 MB/s \n",
            "\u001b[?25hRequirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (3.2.2)\n",
            "Requirement already satisfied: scikit-learn>=0.21.0 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (1.0.1)\n",
            "Requirement already satisfied: gym>=0.17 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (0.17.3)\n",
            "Collecting stable-baselines3[extra]\n",
            "  Downloading stable_baselines3-1.3.0-py3-none-any.whl (174 kB)\n",
            "\u001b[K     |████████████████████████████████| 174 kB 65.2 MB/s \n",
            "\u001b[?25hCollecting ray[default]\n",
            "  Downloading ray-1.9.1-cp37-cp37m-manylinux2014_x86_64.whl (57.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 57.6 MB 1.4 MB/s \n",
            "\u001b[?25hCollecting lz4\n",
            "  Downloading lz4-3.1.10-cp37-cp37m-manylinux2010_x86_64.whl (1.8 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.8 MB 42.9 MB/s \n",
            "\u001b[?25hCollecting tensorboardX\n",
            "  Downloading tensorboardX-2.4.1-py2.py3-none-any.whl (124 kB)\n",
            "\u001b[K     |████████████████████████████████| 124 kB 71.5 MB/s \n",
            "\u001b[?25hCollecting gputil\n",
            "  Downloading GPUtil-1.4.0.tar.gz (5.5 kB)\n",
            "Collecting exchange_calendars\n",
            "  Downloading exchange_calendars-3.5.tar.gz (147 kB)\n",
            "\u001b[K     |████████████████████████████████| 147 kB 35.6 MB/s \n",
            "\u001b[?25hCollecting alpaca_trade_api\n",
            "  Downloading alpaca_trade_api-1.4.3-py3-none-any.whl (36 kB)\n",
            "Collecting ccxt\n",
            "  Downloading ccxt-1.65.38-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 32.7 MB/s \n",
            "\u001b[?25hCollecting jqdatasdk\n",
            "  Downloading jqdatasdk-1.8.10-py3-none-any.whl (153 kB)\n",
            "\u001b[K     |████████████████████████████████| 153 kB 57.3 MB/s \n",
            "\u001b[?25hCollecting wrds\n",
            "  Downloading wrds-3.1.1-py3-none-any.whl (12 kB)\n",
            "Requirement already satisfied: pytest in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (3.6.4)\n",
            "Requirement already satisfied: setuptools>=41.4.0 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (57.4.0)\n",
            "Requirement already satisfied: wheel>=0.33.6 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.3) (0.37.0)\n",
            "Collecting pre-commit\n",
            "  Downloading pre_commit-2.16.0-py2.py3-none-any.whl (191 kB)\n",
            "\u001b[K     |████████████████████████████████| 191 kB 55.1 MB/s \n",
            "\u001b[?25hCollecting pybullet\n",
            "  Downloading pybullet-3.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (90.8 MB)\n",
            "\u001b[K     |████████████████████████████████| 90.8 MB 244 bytes/s \n",
            "\u001b[?25hRequirement already satisfied: torch in /usr/local/lib/python3.7/dist-packages (from elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl->finrl==0.3.3) (1.10.0+cu111)\n",
            "Requirement already satisfied: opencv-python in /usr/local/lib/python3.7/dist-packages (from elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl->finrl==0.3.3) (4.1.2.30)\n",
            "Collecting box2d-py\n",
            "  Downloading box2d_py-2.3.8-cp37-cp37m-manylinux1_x86_64.whl (448 kB)\n",
            "\u001b[K     |████████████████████████████████| 448 kB 50.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: ipython>=3.2.3 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (5.5.0)\n",
            "Requirement already satisfied: pytz>=2014.10 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (2018.9)\n",
            "Requirement already satisfied: scipy>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (1.4.1)\n",
            "Requirement already satisfied: seaborn>=0.7.1 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.11.2)\n",
            "Collecting empyrical>=0.5.0\n",
            "  Downloading empyrical-0.5.5.tar.gz (52 kB)\n",
            "\u001b[K     |████████████████████████████████| 52 kB 1.3 MB/s \n",
            "\u001b[?25hRequirement already satisfied: pandas-datareader>=0.2 in /usr/local/lib/python3.7/dist-packages (from empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.9.0)\n",
            "Requirement already satisfied: pyglet<=1.5.0,>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from gym>=0.17->finrl==0.3.3) (1.5.0)\n",
            "Requirement already satisfied: cloudpickle<1.7.0,>=1.2.0 in /usr/local/lib/python3.7/dist-packages (from gym>=0.17->finrl==0.3.3) (1.3.0)\n",
            "Requirement already satisfied: pexpect in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (4.8.0)\n",
            "Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (1.0.18)\n",
            "Requirement already satisfied: decorator in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (4.4.2)\n",
            "Requirement already satisfied: simplegeneric>0.8 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.8.1)\n",
            "Requirement already satisfied: pygments in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (2.6.1)\n",
            "Requirement already satisfied: traitlets>=4.2 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (5.1.1)\n",
            "Requirement already satisfied: pickleshare in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.7.5)\n",
            "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.3) (1.3.2)\n",
            "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.3) (3.0.6)\n",
            "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.3) (2.8.2)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.3) (0.11.0)\n",
            "Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.7/dist-packages (from pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (2.23.0)\n",
            "Requirement already satisfied: lxml in /usr/local/lib/python3.7/dist-packages (from pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (4.2.6)\n",
            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.7/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (1.15.0)\n",
            "Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.2.5)\n",
            "Requirement already satisfied: future in /usr/local/lib/python3.7/dist-packages (from pyglet<=1.5.0,>=1.4.0->gym>=0.17->finrl==0.3.3) (0.16.0)\n",
            "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (2.10)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (3.0.4)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (2021.10.8)\n",
            "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (1.24.3)\n",
            "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.21.0->finrl==0.3.3) (3.0.0)\n",
            "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.21.0->finrl==0.3.3) (1.1.0)\n",
            "Collecting websocket-client<2,>=0.56.0\n",
            "  Downloading websocket_client-1.2.3-py3-none-any.whl (53 kB)\n",
            "\u001b[K     |████████████████████████████████| 53 kB 1.9 MB/s \n",
            "\u001b[?25hCollecting PyYAML==5.4.1\n",
            "  Downloading PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl (636 kB)\n",
            "\u001b[K     |████████████████████████████████| 636 kB 52.7 MB/s \n",
            "\u001b[?25hCollecting msgpack==1.0.2\n",
            "  Downloading msgpack-1.0.2-cp37-cp37m-manylinux1_x86_64.whl (273 kB)\n",
            "\u001b[K     |████████████████████████████████| 273 kB 60.4 MB/s \n",
            "\u001b[?25hCollecting aiohttp==3.7.4\n",
            "  Downloading aiohttp-3.7.4-cp37-cp37m-manylinux2014_x86_64.whl (1.3 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.3 MB 55.5 MB/s \n",
            "\u001b[?25hCollecting websockets<10,>=8.0\n",
            "  Downloading websockets-9.1-cp37-cp37m-manylinux2010_x86_64.whl (103 kB)\n",
            "\u001b[K     |████████████████████████████████| 103 kB 48.7 MB/s \n",
            "\u001b[?25hCollecting async-timeout<4.0,>=3.0\n",
            "  Downloading async_timeout-3.0.1-py3-none-any.whl (8.2 kB)\n",
            "Requirement already satisfied: typing-extensions>=3.6.5 in /usr/local/lib/python3.7/dist-packages (from aiohttp==3.7.4->alpaca_trade_api->finrl==0.3.3) (3.10.0.2)\n",
            "Collecting multidict<7.0,>=4.5\n",
            "  Downloading multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (160 kB)\n",
            "\u001b[K     |████████████████████████████████| 160 kB 56.6 MB/s \n",
            "\u001b[?25hCollecting yarl<2.0,>=1.0\n",
            "  Downloading yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (271 kB)\n",
            "\u001b[K     |████████████████████████████████| 271 kB 57.3 MB/s \n",
            "\u001b[?25hRequirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.7/dist-packages (from aiohttp==3.7.4->alpaca_trade_api->finrl==0.3.3) (21.2.0)\n",
            "Collecting ccxt\n",
            "  Downloading ccxt-1.65.37-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.36-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.35-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.34-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.33-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.32-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.31-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.30-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.29-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.28-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.27-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.26-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.25-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.24-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.23-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.22-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.21-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.20-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.19-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.18-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.17-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 58.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.16-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 68.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.15-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.14-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.13-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.12-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.11-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 53.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.10-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.9-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.8-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.7-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.6-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.5-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.4-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.3-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.2-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.65.1-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.99-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.98-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.97-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.96-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 33.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.95-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.94-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.93-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.92-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.91-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.90-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.89-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.88-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 73.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.87-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.86-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 28.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.85-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.84-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.83-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.82-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.81-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.80-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 25.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.79-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.78-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.77-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.76-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.75-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.74-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.73-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.72-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.71-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.70-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.69-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.68-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.67-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.66-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.65-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.64-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.63-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.62-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.61-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.60-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.59-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.58-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.57-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.56-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.55-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.54-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 33.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.53-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.52-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.51-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.50-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.49-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 26.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.48-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.47-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.46-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.45-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 26.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.44-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.43-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.42-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.41-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 21.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.40-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.39-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.38-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.37-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.36-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.35-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.34-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.33-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 60.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.32-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.31-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.30-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 11.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.29-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.28-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.27-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.26-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.25-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.24-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.23-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.22-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.21-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.20-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 67.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.19-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.18-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.17-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.16-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.15-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.14-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.13-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.12-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 59.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.11-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 58.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.10-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 59.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.9-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.8-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.7-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.6-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 31.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.4-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.3-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.2-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.64.1-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.100-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.99-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.98-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.97-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.96-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.95-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.94-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.93-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.92-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.91-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.90-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.89-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.88-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.87-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.86-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 29.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.85-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.84-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.83-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.82-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.81-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.80-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.79-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.78-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.77-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.76-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 70.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.75-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.74-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.73-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.72-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.71-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.70-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 25.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.69-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.68-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.67-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.66-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.65-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.64-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.63-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 58.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.62-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.61-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.60-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.59-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.58-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.57-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.56-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.55-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.54-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.53-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.52-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.51-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 60.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.50-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 53.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.49-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.48-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.47-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.46-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 58.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.45-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.44-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.43-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.42-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.41-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.40-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.39-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.38-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.37-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.36-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.35-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.34-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.33-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.32-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 33.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.31-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 34.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.30-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.29-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.28-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.27-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.26-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.25-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.24-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.23-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.22-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.21-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.20-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.19-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.18-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.17-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.16-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.15-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.14-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.13-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.12-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.11-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.10-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.9-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.8-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.7-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.6-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.5-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.4-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.3-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.2-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.63.1-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.99-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 30.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.98-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.97-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.96-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 27.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.95-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.94-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.93-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.92-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.91-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.90-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.89-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 29.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.88-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.87-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 26.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.86-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.85-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 34.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.84-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.83-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.82-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 67.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.81-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 53.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.80-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.79-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.78-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.77-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.76-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.75-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.74-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.73-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.72-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.71-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.70-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.69-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 73.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.68-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 24.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.67-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.66-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.65-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.64-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.63-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.62-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 53.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.61-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.60-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.59-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.58-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.57-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 30.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.56-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.55-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.54-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.53-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.52-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.51-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.50-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.49-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.48-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 32.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.47-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 27.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.46-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.45-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.44-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.43-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 50.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.42-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.41-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.40-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 48.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.39-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.38-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.37-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 35.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.36-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 33.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.35-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.34-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.33-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.32-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.31-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.30-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.29-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 31.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.28-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.27-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.26-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.25-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 29.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.24-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 36.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.23-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.22-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 57.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.21-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.20-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.19-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.18-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 40.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.17-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 52.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.16-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.15-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.14-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.13-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 56.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.12-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.11-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 14.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.10-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.9-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 34.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.8-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 37.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.7-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 41.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.6-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 55.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.5-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.4-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 51.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.3-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.2-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.62.1-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.100-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 65.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.99-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 45.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.98-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 39.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.97-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.96-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.95-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 33.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.94-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 43.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.93-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 46.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.92-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.91-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 47.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.90-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 54.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.89-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 44.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.88-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 49.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.87-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 42.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.86-py2.py3-none-any.whl (2.2 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.2 MB 38.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.85-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 59.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.84-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 45.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.83-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 45.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.82-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 56.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.81-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 41.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.80-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 35.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.79-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 47.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.78-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 20.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.77-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 49.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.76-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 49.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.75-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 46.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.74-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 34.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.73-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 41.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.72-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 44.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.71-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 36.0 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.70-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 37.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.69-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 43.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.68-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 60.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.67-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 50.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.66-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 44.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.65-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 49.7 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.64-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 42.5 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.63-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 51.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.62-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 42.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.61-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 49.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.60-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 57.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.59-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 43.3 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.58-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 44.6 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.57-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 50.4 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.56-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 43.8 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.55-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 45.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.54-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 51.9 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.53-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 43.2 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.52-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 47.1 MB/s \n",
            "\u001b[?25h  Downloading ccxt-1.61.51-py2.py3-none-any.whl (2.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.1 MB 46.6 MB/s \n",
            "\u001b[?25hCollecting aiodns>=1.1.1\n",
            "  Downloading aiodns-3.0.0-py3-none-any.whl (5.0 kB)\n",
            "Collecting yarl<2.0,>=1.0\n",
            "  Downloading yarl-1.6.3-cp37-cp37m-manylinux2014_x86_64.whl (294 kB)\n",
            "\u001b[K     |████████████████████████████████| 294 kB 60.7 MB/s \n",
            "\u001b[?25hCollecting cryptography>=2.6.1\n",
            "  Downloading cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl (3.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.6 MB 42.6 MB/s \n",
            "\u001b[?25hCollecting pycares>=4.0.0\n",
            "  Downloading pycares-4.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (291 kB)\n",
            "\u001b[K     |████████████████████████████████| 291 kB 44.8 MB/s \n",
            "\u001b[?25hRequirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=2.6.1->ccxt->finrl==0.3.3) (1.15.0)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=2.6.1->ccxt->finrl==0.3.3) (2.21)\n",
            "Collecting pyluach\n",
            "  Downloading pyluach-1.3.0-py3-none-any.whl (17 kB)\n",
            "Requirement already satisfied: toolz in /usr/local/lib/python3.7/dist-packages (from exchange_calendars->finrl==0.3.3) (0.11.2)\n",
            "Requirement already satisfied: korean_lunar_calendar in /usr/local/lib/python3.7/dist-packages (from exchange_calendars->finrl==0.3.3) (0.2.1)\n",
            "Requirement already satisfied: SQLAlchemy>=1.2.8 in /usr/local/lib/python3.7/dist-packages (from jqdatasdk->finrl==0.3.3) (1.4.27)\n",
            "Collecting thriftpy2>=0.3.9\n",
            "  Downloading thriftpy2-0.4.14.tar.gz (361 kB)\n",
            "\u001b[K     |████████████████████████████████| 361 kB 50.4 MB/s \n",
            "\u001b[?25hCollecting pymysql>=0.7.6\n",
            "  Downloading PyMySQL-1.0.2-py3-none-any.whl (43 kB)\n",
            "\u001b[K     |████████████████████████████████| 43 kB 1.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.7/dist-packages (from SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.3) (1.1.2)\n",
            "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.3) (4.8.2)\n",
            "Collecting ply<4.0,>=3.4\n",
            "  Downloading ply-3.11-py2.py3-none-any.whl (49 kB)\n",
            "\u001b[K     |████████████████████████████████| 49 kB 5.1 MB/s \n",
            "\u001b[?25hRequirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.3) (3.6.0)\n",
            "Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.7/dist-packages (from pexpect->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.3) (0.7.0)\n",
            "Collecting cfgv>=2.0.0\n",
            "  Downloading cfgv-3.3.1-py2.py3-none-any.whl (7.3 kB)\n",
            "Requirement already satisfied: toml in /usr/local/lib/python3.7/dist-packages (from pre-commit->finrl==0.3.3) (0.10.2)\n",
            "Collecting identify>=1.0.0\n",
            "  Downloading identify-2.4.1-py2.py3-none-any.whl (98 kB)\n",
            "\u001b[K     |████████████████████████████████| 98 kB 7.2 MB/s \n",
            "\u001b[?25hCollecting virtualenv>=20.0.8\n",
            "  Downloading virtualenv-20.11.0-py2.py3-none-any.whl (6.5 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.5 MB 39.6 MB/s \n",
            "\u001b[?25hCollecting nodeenv>=0.11.1\n",
            "  Downloading nodeenv-1.6.0-py2.py3-none-any.whl (21 kB)\n",
            "Requirement already satisfied: filelock<4,>=3.2 in /usr/local/lib/python3.7/dist-packages (from virtualenv>=20.0.8->pre-commit->finrl==0.3.3) (3.4.0)\n",
            "Collecting distlib<1,>=0.3.1\n",
            "  Downloading distlib-0.3.4-py2.py3-none-any.whl (461 kB)\n",
            "\u001b[K     |████████████████████████████████| 461 kB 32.3 MB/s \n",
            "\u001b[?25hCollecting platformdirs<3,>=2\n",
            "  Downloading platformdirs-2.4.1-py3-none-any.whl (14 kB)\n",
            "Requirement already satisfied: pluggy<0.8,>=0.5 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.3) (0.7.1)\n",
            "Requirement already satisfied: py>=1.5.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.3) (1.11.0)\n",
            "Requirement already satisfied: more-itertools>=4.0.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.3) (8.12.0)\n",
            "Requirement already satisfied: atomicwrites>=1.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.3) (1.4.0)\n",
            "Requirement already satisfied: grpcio>=1.28.1 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (1.42.0)\n",
            "Requirement already satisfied: protobuf>=3.15.3 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (3.17.3)\n",
            "Collecting redis>=3.5.0\n",
            "  Downloading redis-4.1.0-py3-none-any.whl (171 kB)\n",
            "\u001b[K     |████████████████████████████████| 171 kB 57.0 MB/s \n",
            "\u001b[?25hRequirement already satisfied: click>=7.0 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (7.1.2)\n",
            "Requirement already satisfied: jsonschema in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (2.6.0)\n",
            "Requirement already satisfied: prometheus-client>=0.7.1 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (0.12.0)\n",
            "Collecting aioredis<2\n",
            "  Downloading aioredis-1.3.1-py3-none-any.whl (65 kB)\n",
            "\u001b[K     |████████████████████████████████| 65 kB 3.6 MB/s \n",
            "\u001b[?25hCollecting py-spy>=0.2.0\n",
            "  Downloading py_spy-0.3.11-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl (3.0 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.0 MB 50.8 MB/s \n",
            "\u001b[?25hCollecting colorful\n",
            "  Downloading colorful-0.5.4-py2.py3-none-any.whl (201 kB)\n",
            "\u001b[K     |████████████████████████████████| 201 kB 70.8 MB/s \n",
            "\u001b[?25hCollecting aiohttp-cors\n",
            "  Downloading aiohttp_cors-0.7.0-py3-none-any.whl (27 kB)\n",
            "Requirement already satisfied: smart-open in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (5.2.1)\n",
            "Collecting aiosignal\n",
            "  Downloading aiosignal-1.2.0-py3-none-any.whl (8.2 kB)\n",
            "Collecting frozenlist\n",
            "  Downloading frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (192 kB)\n",
            "\u001b[K     |████████████████████████████████| 192 kB 7.1 MB/s \n",
            "\u001b[?25hCollecting gpustat>=1.0.0b1\n",
            "  Downloading gpustat-1.0.0b1.tar.gz (82 kB)\n",
            "\u001b[K     |████████████████████████████████| 82 kB 213 kB/s \n",
            "\u001b[?25hCollecting opencensus\n",
            "  Downloading opencensus-0.8.0-py2.py3-none-any.whl (128 kB)\n",
            "\u001b[K     |████████████████████████████████| 128 kB 53.5 MB/s \n",
            "\u001b[?25hCollecting hiredis\n",
            "  Downloading hiredis-2.0.0-cp37-cp37m-manylinux2010_x86_64.whl (85 kB)\n",
            "\u001b[K     |████████████████████████████████| 85 kB 2.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: nvidia-ml-py3>=7.352.0 in /usr/local/lib/python3.7/dist-packages (from gpustat>=1.0.0b1->ray[default]->finrl==0.3.3) (7.352.0)\n",
            "Requirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from gpustat>=1.0.0b1->ray[default]->finrl==0.3.3) (5.4.8)\n",
            "Collecting blessed>=1.17.1\n",
            "  Downloading blessed-1.19.0-py2.py3-none-any.whl (57 kB)\n",
            "\u001b[K     |████████████████████████████████| 57 kB 4.8 MB/s \n",
            "\u001b[?25hCollecting deprecated>=1.2.3\n",
            "  Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)\n",
            "Requirement already satisfied: packaging>=21.3 in /usr/local/lib/python3.7/dist-packages (from redis>=3.5.0->ray[default]->finrl==0.3.3) (21.3)\n",
            "Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.7/dist-packages (from deprecated>=1.2.3->redis>=3.5.0->ray[default]->finrl==0.3.3) (1.13.3)\n",
            "Collecting opencensus-context==0.1.2\n",
            "  Downloading opencensus_context-0.1.2-py2.py3-none-any.whl (4.4 kB)\n",
            "Requirement already satisfied: google-api-core<3.0.0,>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from opencensus->ray[default]->finrl==0.3.3) (1.26.3)\n",
            "Requirement already satisfied: google-auth<2.0dev,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (1.35.0)\n",
            "Requirement already satisfied: googleapis-common-protos<2.0dev,>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (1.53.0)\n",
            "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (4.2.4)\n",
            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (4.8)\n",
            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (0.2.8)\n",
            "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.3) (0.4.8)\n",
            "Requirement already satisfied: tabulate in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.3) (0.8.9)\n",
            "Requirement already satisfied: tensorboard>=2.2.0 in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.3) (2.7.0)\n",
            "Requirement already satisfied: pillow in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.3) (7.1.2)\n",
            "Requirement already satisfied: atari-py~=0.2.0 in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.3) (0.2.9)\n",
            "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (0.12.0)\n",
            "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (0.6.1)\n",
            "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (1.8.0)\n",
            "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (1.0.1)\n",
            "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (3.3.6)\n",
            "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (0.4.6)\n",
            "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (1.3.0)\n",
            "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.3) (3.1.1)\n",
            "Collecting int-date>=0.1.7\n",
            "  Downloading int_date-0.1.8-py2.py3-none-any.whl (5.0 kB)\n",
            "Collecting psycopg2-binary\n",
            "  Downloading psycopg2_binary-2.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.0 MB 32.7 MB/s \n",
            "\u001b[?25hCollecting mock\n",
            "  Downloading mock-4.0.3-py3-none-any.whl (28 kB)\n",
            "Collecting lxml\n",
            "  Downloading lxml-4.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.4 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.4 MB 45.0 MB/s \n",
            "\u001b[?25hRequirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance->finrl==0.3.3) (0.0.10)\n",
            "Building wheels for collected packages: finrl, elegantrl, pyfolio, empyrical, exchange-calendars, gputil, thriftpy2, gpustat\n",
            "  Building wheel for finrl (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for finrl: filename=finrl-0.3.3-py3-none-any.whl size=3885640 sha256=1667a85b9c8c0a7a8efbf04d5ebf154d5d1ea119a32e922d094820030ce0e7e4\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-ufkle1ru/wheels/17/ff/bd/1bc602a0352762b0b24041b88536d803ae343ed0a711fcf55e\n",
            "  Building wheel for elegantrl (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for elegantrl: filename=elegantrl-0.3.2-py3-none-any.whl size=168744 sha256=7773813204e1a2954730bd149444640d5155458fc82b6910ec4e661879797016\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-ufkle1ru/wheels/99/85/5e/86cb3a9f47adfca5e248295e93113e1b298d60883126d62c84\n",
            "  Building wheel for pyfolio (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for pyfolio: filename=pyfolio-0.9.2+75.g4b901f6-py3-none-any.whl size=75775 sha256=e3753b24d032afc5ef0b133c50557002ca9fed8416e2205e1547fc81af5c124a\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-ufkle1ru/wheels/ef/09/e5/2c1bf37c050d22557c080deb1be986d06424627c04aeca19b9\n",
            "  Building wheel for empyrical (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for empyrical: filename=empyrical-0.5.5-py3-none-any.whl size=39777 sha256=6cc78a6b3f88187e2798221487acba0361bb1d094b6c82496348fb4c85f7686b\n",
            "  Stored in directory: /root/.cache/pip/wheels/d9/91/4b/654fcff57477efcf149eaca236da2fce991526cbab431bf312\n",
            "  Building wheel for exchange-calendars (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for exchange-calendars: filename=exchange_calendars-3.5-py3-none-any.whl size=179487 sha256=3d877d78e29a28c4b098f4a0b1d0106458d7f73b52f6c7a43d0757d55c11d44b\n",
            "  Stored in directory: /root/.cache/pip/wheels/69/21/43/b6ae2605dd767f6cd5a5b0b70c93a9a75823e44b3ccb92bce7\n",
            "  Building wheel for gputil (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for gputil: filename=GPUtil-1.4.0-py3-none-any.whl size=7411 sha256=33dcd980f1b32f0582d029fcef126ae53327fb90724eee8c33bc3b4dbebda4b1\n",
            "  Stored in directory: /root/.cache/pip/wheels/6e/f8/83/534c52482d6da64622ddbf72cd93c35d2ef2881b78fd08ff0c\n",
            "  Building wheel for thriftpy2 (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for thriftpy2: filename=thriftpy2-0.4.14-cp37-cp37m-linux_x86_64.whl size=940507 sha256=429244bf5fd89014c79f01bf0e4a59477258cd2b88978e3125b54f4bd62a88f5\n",
            "  Stored in directory: /root/.cache/pip/wheels/2a/f5/49/9c0d851aa64b58db72883cf9393cc824d536bdf13f5c83cff4\n",
            "  Building wheel for gpustat (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for gpustat: filename=gpustat-1.0.0b1-py3-none-any.whl size=15979 sha256=b831a9dba6682b3e0a7ae05d7c2ba465918426c72474917e56e0850ac8c73263\n",
            "  Stored in directory: /root/.cache/pip/wheels/1a/16/e2/3e2437fba4c4b6a97a97bd96fce5d14e66cff5c4966fb1cc8c\n",
            "Successfully built finrl elegantrl pyfolio empyrical exchange-calendars gputil thriftpy2 gpustat\n",
            "Installing collected packages: multidict, yarl, lxml, deprecated, async-timeout, redis, PyYAML, pycares, ply, platformdirs, opencensus-context, msgpack, hiredis, frozenlist, distlib, blessed, aiohttp, websockets, websocket-client, virtualenv, thriftpy2, tensorboardX, stable-baselines3, ray, pymysql, pyluach, pybullet, py-spy, psycopg2-binary, opencensus, nodeenv, mock, int-date, identify, gpustat, empyrical, cryptography, colorful, cfgv, box2d-py, aiosignal, aioredis, aiohttp-cors, aiodns, yfinance, wrds, stockstats, pyfolio, pre-commit, lz4, jqdatasdk, gputil, exchange-calendars, elegantrl, ccxt, alpaca-trade-api, finrl\n",
            "  Attempting uninstall: lxml\n",
            "    Found existing installation: lxml 4.2.6\n",
            "    Uninstalling lxml-4.2.6:\n",
            "      Successfully uninstalled lxml-4.2.6\n",
            "  Attempting uninstall: PyYAML\n",
            "    Found existing installation: PyYAML 3.13\n",
            "    Uninstalling PyYAML-3.13:\n",
            "      Successfully uninstalled PyYAML-3.13\n",
            "  Attempting uninstall: msgpack\n",
            "    Found existing installation: msgpack 1.0.3\n",
            "    Uninstalling msgpack-1.0.3:\n",
            "      Successfully uninstalled msgpack-1.0.3\n",
            "Successfully installed PyYAML-5.4.1 aiodns-3.0.0 aiohttp-3.7.4 aiohttp-cors-0.7.0 aioredis-1.3.1 aiosignal-1.2.0 alpaca-trade-api-1.4.3 async-timeout-3.0.1 blessed-1.19.0 box2d-py-2.3.8 ccxt-1.61.51 cfgv-3.3.1 colorful-0.5.4 cryptography-36.0.1 deprecated-1.2.13 distlib-0.3.4 elegantrl-0.3.2 empyrical-0.5.5 exchange-calendars-3.5 finrl-0.3.3 frozenlist-1.2.0 gpustat-1.0.0b1 gputil-1.4.0 hiredis-2.0.0 identify-2.4.1 int-date-0.1.8 jqdatasdk-1.8.10 lxml-4.7.1 lz4-3.1.10 mock-4.0.3 msgpack-1.0.2 multidict-5.2.0 nodeenv-1.6.0 opencensus-0.8.0 opencensus-context-0.1.2 platformdirs-2.4.1 ply-3.11 pre-commit-2.16.0 psycopg2-binary-2.9.2 py-spy-0.3.11 pybullet-3.2.1 pycares-4.1.2 pyfolio-0.9.2+75.g4b901f6 pyluach-1.3.0 pymysql-1.0.2 ray-1.9.1 redis-4.1.0 stable-baselines3-1.3.0 stockstats-0.3.2 tensorboardX-2.4.1 thriftpy2-0.4.14 virtualenv-20.11.0 websocket-client-1.2.3 websockets-9.1 wrds-3.1.1 yarl-1.6.3 yfinance-0.1.67\n"
          ]
        }
      ],
      "source": [
        "## install finrl library\n",
        "!pip install git+https://github.com/AI4Finance-LLC/FinRL-Library.git"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "w9A8CN5R5PuZ"
      },
      "outputs": [],
      "source": [
        "from finrl.apps import config\n",
        "import os\n",
        "if not os.path.exists(\"./\" + config.DATA_SAVE_DIR):\n",
        "    os.makedirs(\"./\" + config.DATA_SAVE_DIR)\n",
        "if not os.path.exists(\"./\" + config.TRAINED_MODEL_DIR):\n",
        "    os.makedirs(\"./\" + config.TRAINED_MODEL_DIR)\n",
        "if not os.path.exists(\"./\" + config.TENSORBOARD_LOG_DIR):\n",
        "    os.makedirs(\"./\" + config.TENSORBOARD_LOG_DIR)\n",
        "if not os.path.exists(\"./\" + config.RESULTS_DIR):\n",
        "    os.makedirs(\"./\" + config.RESULTS_DIR)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "osBHhVysOEzi"
      },
      "source": [
        "\n",
        "<a id='1.2'></a>\n",
        "## 2.2. Check if the additional packages needed are present, if not install them. \n",
        "* Yahoo Finance API\n",
        "* pandas\n",
        "* numpy\n",
        "* matplotlib\n",
        "* stockstats\n",
        "* OpenAI gym\n",
        "* stable-baselines\n",
        "* tensorflow\n",
        "* pyfolio"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nGv01K8Sh1hn"
      },
      "source": [
        "<a id='1.3'></a>\n",
        "## 2.3. Import Packages"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "lPqeTTwoh1hn",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "10b08480-3a0c-4826-8e51-f94ce97ab84a"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/pyfolio/pos.py:27: UserWarning: Module \"zipline.assets\" not found; multipliers will not be applied to position notionals.\n",
            "  'Module \"zipline.assets\" not found; multipliers will not be applied'\n"
          ]
        }
      ],
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import matplotlib\n",
        "import matplotlib.pyplot as plt\n",
        "# matplotlib.use('Agg')\n",
        "import datetime\n",
        "\n",
        "%matplotlib inline\n",
        "from finrl.finrl_meta.preprocessor.yahoodownloader import YahooDownloader\n",
        "from finrl.finrl_meta.preprocessor.preprocessors import FeatureEngineer, data_split\n",
        "from finrl.finrl_meta.env_stock_trading.env_stocktrading import StockTradingEnv\n",
        "from finrl.drl_agents.stablebaselines3.models import DRLAgent\n",
        "from finrl.finrl_meta.data_processor import DataProcessor\n",
        "\n",
        "from finrl.plot import backtest_stats, backtest_plot, get_daily_return, get_baseline\n",
        "from pprint import pprint\n",
        "\n",
        "import sys\n",
        "sys.path.append(\"../FinRL-Library\")\n",
        "\n",
        "import itertools"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "T2owTj985RW4"
      },
      "source": [
        "<a id='1.4'></a>\n",
        "## 2.4. Create Folders"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "A289rQWMh1hq"
      },
      "source": [
        "<a id='2'></a>\n",
        "# Part 3. Download Data\n",
        "Yahoo Finance is a website that provides stock data, financial news, financial reports, etc. All the data provided by Yahoo Finance is free.\n",
        "* FinRL uses a class **YahooDownloader** to fetch data from Yahoo Finance API\n",
        "* Call Limit: Using the Public API (without authentication), you are limited to 2,000 requests per hour per IP (or up to a total of 48,000 requests a day).\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NPeQ7iS-LoMm"
      },
      "source": [
        "\n",
        "\n",
        "-----\n",
        "class YahooDownloader:\n",
        "    Provides methods for retrieving daily stock data from\n",
        "    Yahoo Finance API\n",
        "\n",
        "    Attributes\n",
        "    ----------\n",
        "        start_date : str\n",
        "            start date of the data (modified from config.py)\n",
        "        end_date : str\n",
        "            end date of the data (modified from config.py)\n",
        "        ticker_list : list\n",
        "            a list of stock tickers (modified from config.py)\n",
        "\n",
        "    Methods\n",
        "    -------\n",
        "    fetch_data()\n",
        "        Fetches data from yahoo API\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "h3XJnvrbLp-C",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "5302d7c0-1c68-4c6e-b30e-b1395bdc109e"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            },
            "text/plain": [
              "'2009-01-01'"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ],
      "source": [
        "# from config.py start_date is a string\n",
        "config.START_DATE"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "FUnY8WEfLq3C",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "35dd8c5b-d58f-49b8-e4df-ae7e122448cd"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            },
            "text/plain": [
              "'2021-10-31'"
            ]
          },
          "metadata": {},
          "execution_count": 5
        }
      ],
      "source": [
        "# from config.py end_date is a string\n",
        "config.END_DATE"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "yCKm4om-s9kE",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "83c7f894-3757-473b-8afb-a904e6caabda"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "Shape of DataFrame:  (94331, 8)\n"
          ]
        }
      ],
      "source": [
        "df = YahooDownloader(start_date = '2009-01-01',\n",
        "                     end_date = '2021-10-31',\n",
        "                     ticker_list = config.DOW_30_TICKER).fetch_data()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "JzqRRTOX6aFu",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "7a991dfe-f39c-40db-ec44-7c416cdce7dc"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "['AXP', 'AMGN', 'AAPL', 'BA', 'CAT', 'CSCO', 'CVX', 'GS', 'HD', 'HON', 'IBM', 'INTC', 'JNJ', 'KO', 'JPM', 'MCD', 'MMM', 'MRK', 'MSFT', 'NKE', 'PG', 'TRV', 'UNH', 'CRM', 'VZ', 'V', 'WBA', 'WMT', 'DIS', 'DOW']\n"
          ]
        }
      ],
      "source": [
        "print(config.DOW_30_TICKER)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "CV3HrZHLh1hy",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "5267773c-399c-4ec9-d4d5-13ab1e4cced0"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(94331, 8)"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ],
      "source": [
        "df.shape"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "4hYkeaPiICHS",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "outputId": "210fade5-e912-40df-be99-4ad00bdb9d2f"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-66e2881b-1115-4eee-b48f-35c673427c34\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>tic</th>\n",
              "      <th>day</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615879</td>\n",
              "      <td>6547900</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.618542</td>\n",
              "      <td>10955700</td>\n",
              "      <td>AXP</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941105</td>\n",
              "      <td>7010200</td>\n",
              "      <td>BA</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475788</td>\n",
              "      <td>7117200</td>\n",
              "      <td>CAT</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-66e2881b-1115-4eee-b48f-35c673427c34')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-66e2881b-1115-4eee-b48f-35c673427c34 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-66e2881b-1115-4eee-b48f-35c673427c34');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "         date       open       high        low      close     volume   tic  day\n",
              "0  2009-01-02   3.067143   3.251429   3.041429   2.778782  746015200  AAPL    4\n",
              "1  2009-01-02  58.590000  59.080002  57.750000  45.615879    6547900  AMGN    4\n",
              "2  2009-01-02  18.570000  19.520000  18.400000  15.618542   10955700   AXP    4\n",
              "3  2009-01-02  42.799999  45.560001  42.779999  33.941105    7010200    BA    4\n",
              "4  2009-01-02  44.910000  46.980000  44.709999  32.475788    7117200   CAT    4"
            ]
          },
          "metadata": {},
          "execution_count": 9
        }
      ],
      "source": [
        "df.sort_values(['date','tic'],ignore_index=True).head()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uqC6c40Zh1iH"
      },
      "source": [
        "# Part 4: Preprocess Data\n",
        "Data preprocessing is a crucial step for training a high quality machine learning model. We need to check for missing data and do feature engineering in order to convert the data into a model-ready state.\n",
        "* Add technical indicators. In practical trading, various information needs to be taken into account, for example the historical stock prices, current holding shares, technical indicators, etc. In this article, we demonstrate two trend-following technical indicators: MACD and RSI.\n",
        "* Add turbulence index. Risk-aversion reflects whether an investor will choose to preserve the capital. It also influences one's trading strategy when facing different market volatility level. To control the risk in a worst-case scenario, such as financial crisis of 2007–2008, FinRL employs the financial turbulence index that measures extreme asset price fluctuation."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "PmKP-1ii3RLS",
        "pycharm": {
          "name": "#%%\n"
        },
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "0708badb-77ef-4c86-f77c-6525f0e8934d"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Successfully added technical indicators\n",
            "\r[*********************100%***********************]  1 of 1 completed\n",
            "Shape of DataFrame:  (3229, 8)\n",
            "Successfully added vix\n",
            "Successfully added turbulence index\n"
          ]
        }
      ],
      "source": [
        "fe = FeatureEngineer(\n",
        "                    use_technical_indicator=True,\n",
        "                    tech_indicator_list = config.TECHNICAL_INDICATORS_LIST,\n",
        "                    use_vix=True,\n",
        "                    use_turbulence=True,\n",
        "                    user_defined_feature = False)\n",
        "\n",
        "processed = fe.preprocess_data(df)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "Kixon2tR3RLT"
      },
      "outputs": [],
      "source": [
        "list_ticker = processed[\"tic\"].unique().tolist()\n",
        "list_date = list(pd.date_range(processed['date'].min(),processed['date'].max()).astype(str))\n",
        "combination = list(itertools.product(list_date,list_ticker))\n",
        "\n",
        "processed_full = pd.DataFrame(combination,columns=[\"date\",\"tic\"]).merge(processed,on=[\"date\",\"tic\"],how=\"left\")\n",
        "processed_full = processed_full[processed_full['date'].isin(processed['date'])]\n",
        "processed_full = processed_full.sort_values(['date','tic'])\n",
        "\n",
        "processed_full = processed_full.fillna(0)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "grvhGJJII3Xn",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 600
        },
        "outputId": "733758c3-3552-4aa5-e1f9-789bd4ce0c92"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-00babc9a-d419-4fa2-8bb4-498912a1cb1c\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>day</th>\n",
              "      <th>macd</th>\n",
              "      <th>boll_ub</th>\n",
              "      <th>boll_lb</th>\n",
              "      <th>rsi_30</th>\n",
              "      <th>cci_30</th>\n",
              "      <th>dx_30</th>\n",
              "      <th>close_30_sma</th>\n",
              "      <th>close_60_sma</th>\n",
              "      <th>vix</th>\n",
              "      <th>turbulence</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615879</td>\n",
              "      <td>6547900.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>45.615879</td>\n",
              "      <td>45.615879</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AXP</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.618542</td>\n",
              "      <td>10955700.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>15.618542</td>\n",
              "      <td>15.618542</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>BA</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941105</td>\n",
              "      <td>7010200.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>33.941105</td>\n",
              "      <td>33.941105</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CAT</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475788</td>\n",
              "      <td>7117200.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>32.475788</td>\n",
              "      <td>32.475788</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CRM</td>\n",
              "      <td>8.025000</td>\n",
              "      <td>8.550000</td>\n",
              "      <td>7.912500</td>\n",
              "      <td>8.505000</td>\n",
              "      <td>4069200.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>8.505000</td>\n",
              "      <td>8.505000</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>6</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CSCO</td>\n",
              "      <td>16.410000</td>\n",
              "      <td>17.000000</td>\n",
              "      <td>16.250000</td>\n",
              "      <td>12.421844</td>\n",
              "      <td>40980600.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>12.421844</td>\n",
              "      <td>12.421844</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CVX</td>\n",
              "      <td>74.230003</td>\n",
              "      <td>77.300003</td>\n",
              "      <td>73.580002</td>\n",
              "      <td>45.650547</td>\n",
              "      <td>13695900.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>45.650547</td>\n",
              "      <td>45.650547</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>8</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>DIS</td>\n",
              "      <td>22.760000</td>\n",
              "      <td>24.030001</td>\n",
              "      <td>22.500000</td>\n",
              "      <td>20.597496</td>\n",
              "      <td>9796600.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>20.597496</td>\n",
              "      <td>20.597496</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>GS</td>\n",
              "      <td>84.019997</td>\n",
              "      <td>87.620003</td>\n",
              "      <td>82.190002</td>\n",
              "      <td>71.587753</td>\n",
              "      <td>14088500.0</td>\n",
              "      <td>4.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>3.003272</td>\n",
              "      <td>2.671567</td>\n",
              "      <td>100.0</td>\n",
              "      <td>66.666667</td>\n",
              "      <td>100.0</td>\n",
              "      <td>71.587753</td>\n",
              "      <td>71.587753</td>\n",
              "      <td>39.189999</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-00babc9a-d419-4fa2-8bb4-498912a1cb1c')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-00babc9a-d419-4fa2-8bb4-498912a1cb1c button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-00babc9a-d419-4fa2-8bb4-498912a1cb1c');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "         date   tic       open  ...  close_60_sma        vix  turbulence\n",
              "0  2009-01-02  AAPL   3.067143  ...      2.778782  39.189999         0.0\n",
              "1  2009-01-02  AMGN  58.590000  ...     45.615879  39.189999         0.0\n",
              "2  2009-01-02   AXP  18.570000  ...     15.618542  39.189999         0.0\n",
              "3  2009-01-02    BA  42.799999  ...     33.941105  39.189999         0.0\n",
              "4  2009-01-02   CAT  44.910000  ...     32.475788  39.189999         0.0\n",
              "5  2009-01-02   CRM   8.025000  ...      8.505000  39.189999         0.0\n",
              "6  2009-01-02  CSCO  16.410000  ...     12.421844  39.189999         0.0\n",
              "7  2009-01-02   CVX  74.230003  ...     45.650547  39.189999         0.0\n",
              "8  2009-01-02   DIS  22.760000  ...     20.597496  39.189999         0.0\n",
              "9  2009-01-02    GS  84.019997  ...     71.587753  39.189999         0.0\n",
              "\n",
              "[10 rows x 18 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 12
        }
      ],
      "source": [
        "processed_full.sort_values(['date','tic'],ignore_index=True).head(10)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-QsYaY0Dh1iw"
      },
      "source": [
        "<a id='4'></a>\n",
        "# Part 5. Design Environment\n",
        "Considering the stochastic and interactive nature of the automated stock trading tasks, a financial task is modeled as a **Markov Decision Process (MDP)** problem. The training process involves observing stock price change, taking an action and reward's calculation to have the agent adjusting its strategy accordingly. By interacting with the environment, the trading agent will derive a trading strategy with the maximized rewards as time proceeds.\n",
        "\n",
        "Our trading environments, based on OpenAI Gym framework, simulate live stock markets with real market data according to the principle of time-driven simulation.\n",
        "\n",
        "The action space describes the allowed actions that the agent interacts with the environment. Normally, action a includes three actions: {-1, 0, 1}, where -1, 0, 1 represent selling, holding, and buying one share. Also, an action can be carried upon multiple shares. We use an action space {-k,…,-1, 0, 1, …, k}, where k denotes the number of shares to buy and -k denotes the number of shares to sell. For example, \"Buy 10 shares of AAPL\" or \"Sell 10 shares of AAPL\" are 10 or -10, respectively. The continuous action space needs to be normalized to [-1, 1], since the policy is defined on a Gaussian distribution, which needs to be normalized and symmetric."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5TOhcryx44bb"
      },
      "source": [
        "## Training data split: 2009-01-01 to 2020-07-01\n",
        "## Trade data split: 2020-07-01 to 2021-10-31"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "W0qaVGjLtgbI",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "ca8d1a43-ffc3-4fc3-efa9-4de9a9065842"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "83897\n",
            "9744\n"
          ]
        }
      ],
      "source": [
        "train = data_split(processed_full, '2009-01-01','2020-07-01')\n",
        "trade = data_split(processed_full, '2020-07-01','2021-10-31')\n",
        "print(len(train))\n",
        "print(len(trade))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "p52zNCOhTtLR",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "outputId": "b3ad3e10-376f-4186-f875-0331708c5e14"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-618bcac5-931b-4e49-bb84-d69c1785cb5c\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>day</th>\n",
              "      <th>macd</th>\n",
              "      <th>boll_ub</th>\n",
              "      <th>boll_lb</th>\n",
              "      <th>rsi_30</th>\n",
              "      <th>cci_30</th>\n",
              "      <th>dx_30</th>\n",
              "      <th>close_30_sma</th>\n",
              "      <th>close_60_sma</th>\n",
              "      <th>vix</th>\n",
              "      <th>turbulence</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2892</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>UNH</td>\n",
              "      <td>288.570007</td>\n",
              "      <td>296.450012</td>\n",
              "      <td>287.660004</td>\n",
              "      <td>288.628418</td>\n",
              "      <td>2932900.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.019534</td>\n",
              "      <td>304.825243</td>\n",
              "      <td>272.053937</td>\n",
              "      <td>52.413059</td>\n",
              "      <td>-25.815144</td>\n",
              "      <td>1.846804</td>\n",
              "      <td>288.872994</td>\n",
              "      <td>281.832978</td>\n",
              "      <td>30.43</td>\n",
              "      <td>12.918777</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2892</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>V</td>\n",
              "      <td>191.490005</td>\n",
              "      <td>193.750000</td>\n",
              "      <td>190.160004</td>\n",
              "      <td>191.412445</td>\n",
              "      <td>9040100.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.052500</td>\n",
              "      <td>199.454088</td>\n",
              "      <td>185.696437</td>\n",
              "      <td>53.021038</td>\n",
              "      <td>-51.516660</td>\n",
              "      <td>2.013358</td>\n",
              "      <td>192.162884</td>\n",
              "      <td>182.320812</td>\n",
              "      <td>30.43</td>\n",
              "      <td>12.918777</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2892</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>VZ</td>\n",
              "      <td>54.919998</td>\n",
              "      <td>55.290001</td>\n",
              "      <td>54.360001</td>\n",
              "      <td>51.604500</td>\n",
              "      <td>17414800.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.447763</td>\n",
              "      <td>55.232496</td>\n",
              "      <td>49.916930</td>\n",
              "      <td>48.097047</td>\n",
              "      <td>-50.926627</td>\n",
              "      <td>8.508886</td>\n",
              "      <td>52.255363</td>\n",
              "      <td>52.718949</td>\n",
              "      <td>30.43</td>\n",
              "      <td>12.918777</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2892</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>WBA</td>\n",
              "      <td>42.119999</td>\n",
              "      <td>42.580002</td>\n",
              "      <td>41.759998</td>\n",
              "      <td>39.892540</td>\n",
              "      <td>4782100.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.085830</td>\n",
              "      <td>43.544548</td>\n",
              "      <td>37.287954</td>\n",
              "      <td>48.830190</td>\n",
              "      <td>-14.445141</td>\n",
              "      <td>1.500723</td>\n",
              "      <td>39.994176</td>\n",
              "      <td>39.789724</td>\n",
              "      <td>30.43</td>\n",
              "      <td>12.918777</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2892</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>WMT</td>\n",
              "      <td>119.220001</td>\n",
              "      <td>120.129997</td>\n",
              "      <td>118.540001</td>\n",
              "      <td>116.994614</td>\n",
              "      <td>6836400.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>-0.893234</td>\n",
              "      <td>120.371806</td>\n",
              "      <td>114.363670</td>\n",
              "      <td>48.159665</td>\n",
              "      <td>-69.914694</td>\n",
              "      <td>3.847271</td>\n",
              "      <td>118.672996</td>\n",
              "      <td>120.623193</td>\n",
              "      <td>30.43</td>\n",
              "      <td>12.918777</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-618bcac5-931b-4e49-bb84-d69c1785cb5c')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-618bcac5-931b-4e49-bb84-d69c1785cb5c button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-618bcac5-931b-4e49-bb84-d69c1785cb5c');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "            date  tic        open  ...  close_60_sma    vix  turbulence\n",
              "2892  2020-06-30  UNH  288.570007  ...    281.832978  30.43   12.918777\n",
              "2892  2020-06-30    V  191.490005  ...    182.320812  30.43   12.918777\n",
              "2892  2020-06-30   VZ   54.919998  ...     52.718949  30.43   12.918777\n",
              "2892  2020-06-30  WBA   42.119999  ...     39.789724  30.43   12.918777\n",
              "2892  2020-06-30  WMT  119.220001  ...    120.623193  30.43   12.918777\n",
              "\n",
              "[5 rows x 18 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 14
        }
      ],
      "source": [
        "train.tail()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "k9zU9YaTTvFq",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "outputId": "72213585-39a3-4bff-c031-874ec0ca06f9"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-bf423a8f-07cb-4099-80bf-84651b53c5c4\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>day</th>\n",
              "      <th>macd</th>\n",
              "      <th>boll_ub</th>\n",
              "      <th>boll_lb</th>\n",
              "      <th>rsi_30</th>\n",
              "      <th>cci_30</th>\n",
              "      <th>dx_30</th>\n",
              "      <th>close_30_sma</th>\n",
              "      <th>close_60_sma</th>\n",
              "      <th>vix</th>\n",
              "      <th>turbulence</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2020-07-01</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>91.279999</td>\n",
              "      <td>91.839996</td>\n",
              "      <td>90.977501</td>\n",
              "      <td>90.151405</td>\n",
              "      <td>110737200.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>3.022880</td>\n",
              "      <td>92.953798</td>\n",
              "      <td>80.400058</td>\n",
              "      <td>62.807136</td>\n",
              "      <td>107.487539</td>\n",
              "      <td>29.730532</td>\n",
              "      <td>84.164182</td>\n",
              "      <td>77.930892</td>\n",
              "      <td>28.620001</td>\n",
              "      <td>53.068262</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2020-07-01</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>235.520004</td>\n",
              "      <td>256.230011</td>\n",
              "      <td>232.580002</td>\n",
              "      <td>244.159134</td>\n",
              "      <td>6575800.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>3.697038</td>\n",
              "      <td>236.273230</td>\n",
              "      <td>203.552000</td>\n",
              "      <td>61.279647</td>\n",
              "      <td>271.769196</td>\n",
              "      <td>46.806139</td>\n",
              "      <td>218.441970</td>\n",
              "      <td>219.532869</td>\n",
              "      <td>28.620001</td>\n",
              "      <td>53.068262</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2020-07-01</td>\n",
              "      <td>AXP</td>\n",
              "      <td>95.250000</td>\n",
              "      <td>96.959999</td>\n",
              "      <td>93.639999</td>\n",
              "      <td>92.579544</td>\n",
              "      <td>3301000.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>-0.391248</td>\n",
              "      <td>111.015324</td>\n",
              "      <td>88.229326</td>\n",
              "      <td>48.504813</td>\n",
              "      <td>-66.339693</td>\n",
              "      <td>3.142448</td>\n",
              "      <td>97.765431</td>\n",
              "      <td>91.181246</td>\n",
              "      <td>28.620001</td>\n",
              "      <td>53.068262</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2020-07-01</td>\n",
              "      <td>BA</td>\n",
              "      <td>185.880005</td>\n",
              "      <td>190.610001</td>\n",
              "      <td>180.039993</td>\n",
              "      <td>180.320007</td>\n",
              "      <td>49036700.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>5.443193</td>\n",
              "      <td>220.721139</td>\n",
              "      <td>160.932863</td>\n",
              "      <td>50.925771</td>\n",
              "      <td>24.220608</td>\n",
              "      <td>15.932920</td>\n",
              "      <td>176.472335</td>\n",
              "      <td>155.614168</td>\n",
              "      <td>28.620001</td>\n",
              "      <td>53.068262</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2020-07-01</td>\n",
              "      <td>CAT</td>\n",
              "      <td>129.380005</td>\n",
              "      <td>129.399994</td>\n",
              "      <td>125.879997</td>\n",
              "      <td>121.818489</td>\n",
              "      <td>2807800.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>1.284937</td>\n",
              "      <td>131.887581</td>\n",
              "      <td>114.449377</td>\n",
              "      <td>52.865426</td>\n",
              "      <td>35.546958</td>\n",
              "      <td>14.457404</td>\n",
              "      <td>120.567700</td>\n",
              "      <td>114.745772</td>\n",
              "      <td>28.620001</td>\n",
              "      <td>53.068262</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-bf423a8f-07cb-4099-80bf-84651b53c5c4')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-bf423a8f-07cb-4099-80bf-84651b53c5c4 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-bf423a8f-07cb-4099-80bf-84651b53c5c4');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "         date   tic        open  ...  close_60_sma        vix  turbulence\n",
              "0  2020-07-01  AAPL   91.279999  ...     77.930892  28.620001   53.068262\n",
              "0  2020-07-01  AMGN  235.520004  ...    219.532869  28.620001   53.068262\n",
              "0  2020-07-01   AXP   95.250000  ...     91.181246  28.620001   53.068262\n",
              "0  2020-07-01    BA  185.880005  ...    155.614168  28.620001   53.068262\n",
              "0  2020-07-01   CAT  129.380005  ...    114.745772  28.620001   53.068262\n",
              "\n",
              "[5 rows x 18 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 15
        }
      ],
      "source": [
        "trade.head()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "zYN573SOHhxG",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "7f228183-abe3-4477-f574-3c9b25c62cd8"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "['macd',\n",
              " 'boll_ub',\n",
              " 'boll_lb',\n",
              " 'rsi_30',\n",
              " 'cci_30',\n",
              " 'dx_30',\n",
              " 'close_30_sma',\n",
              " 'close_60_sma']"
            ]
          },
          "metadata": {},
          "execution_count": 16
        }
      ],
      "source": [
        "config.TECHNICAL_INDICATORS_LIST"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "Q2zqII8rMIqn",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "1f54d044-e2d3-4a34-c041-e913d686654e"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Stock Dimension: 29, State Space: 291\n"
          ]
        }
      ],
      "source": [
        "stock_dimension = len(train.tic.unique())\n",
        "state_space = 1 + 2*stock_dimension + len(config.TECHNICAL_INDICATORS_LIST)*stock_dimension\n",
        "print(f\"Stock Dimension: {stock_dimension}, State Space: {state_space}\")\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "AWyp84Ltto19"
      },
      "outputs": [],
      "source": [
        "env_kwargs = {\n",
        "    \"hmax\": 100, \n",
        "    \"initial_amount\": 1000000, \n",
        "    \"buy_cost_pct\": 0.001,\n",
        "    \"sell_cost_pct\": 0.001,\n",
        "    \"state_space\": state_space, \n",
        "    \"stock_dim\": stock_dimension, \n",
        "    \"tech_indicator_list\": config.TECHNICAL_INDICATORS_LIST, \n",
        "    \"action_space\": stock_dimension, \n",
        "    \"reward_scaling\": 1e-4\n",
        "    \n",
        "}\n",
        "\n",
        "e_train_gym = StockTradingEnv(df = train, **env_kwargs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "64EoqOrQjiVf"
      },
      "source": [
        "## Environment for Training\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "id": "xwSvvPjutpqS",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "deeaef07-afda-4ca1-fea8-99384224c7cf"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "<class 'stable_baselines3.common.vec_env.dummy_vec_env.DummyVecEnv'>\n"
          ]
        }
      ],
      "source": [
        "env_train, _ = e_train_gym.get_sb_env()\n",
        "print(type(env_train))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HMNR5nHjh1iz"
      },
      "source": [
        "<a id='5'></a>\n",
        "# Part 6: Implement DRL Algorithms\n",
        "* The implementation of the DRL algorithms are based on **OpenAI Baselines** and **Stable Baselines**. Stable Baselines is a fork of OpenAI Baselines, with a major structural refactoring, and code cleanups.\n",
        "* FinRL library includes fine-tuned standard DRL algorithms, such as DQN, DDPG,\n",
        "Multi-Agent DDPG, PPO, SAC, A2C and TD3. We also allow users to\n",
        "design their own DRL algorithms by adapting these DRL algorithms."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "id": "364PsqckttcQ"
      },
      "outputs": [],
      "source": [
        "agent = DRLAgent(env = env_train)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YDmqOyF9h1iz"
      },
      "source": [
        "### Model Training: 5 models, A2C DDPG, PPO, TD3, SAC\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uijiWgkuh1jB"
      },
      "source": [
        "### Model 1: A2C\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "id": "GUCnkn-HIbmj",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a90a7a60-21a5-47e1-b683-1f7cbb4b8bc0"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'n_steps': 5, 'ent_coef': 0.01, 'learning_rate': 0.0007}\n",
            "Using cpu device\n"
          ]
        }
      ],
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "model_a2c = agent.get_model(\"a2c\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "id": "0GVpkWGqH4-D",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "outputId": "570d540f-abe9-402b-e0cc-f9b007228e8e"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 77         |\n",
            "|    iterations         | 100        |\n",
            "|    time_elapsed       | 6          |\n",
            "|    total_timesteps    | 500        |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.2      |\n",
            "|    explained_variance | -1.19e-07  |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 99         |\n",
            "|    policy_loss        | -23.3      |\n",
            "|    reward             | 0.16407855 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 1.02       |\n",
            "--------------------------------------\n",
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 80         |\n",
            "|    iterations         | 200        |\n",
            "|    time_elapsed       | 12         |\n",
            "|    total_timesteps    | 1000       |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.3      |\n",
            "|    explained_variance | 0          |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 199        |\n",
            "|    policy_loss        | -23.2      |\n",
            "|    reward             | -0.7490468 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 2.69       |\n",
            "--------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 80        |\n",
            "|    iterations         | 300       |\n",
            "|    time_elapsed       | 18        |\n",
            "|    total_timesteps    | 1500      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -41.2     |\n",
            "|    explained_variance | 0         |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 299       |\n",
            "|    policy_loss        | -394      |\n",
            "|    reward             | 7.1691494 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 87        |\n",
            "-------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 79        |\n",
            "|    iterations         | 400       |\n",
            "|    time_elapsed       | 25        |\n",
            "|    total_timesteps    | 2000      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -41.2     |\n",
            "|    explained_variance | 1.19e-07  |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 399       |\n",
            "|    policy_loss        | -19       |\n",
            "|    reward             | 2.3222716 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 7.21      |\n",
            "-------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 81        |\n",
            "|    iterations         | 500       |\n",
            "|    time_elapsed       | 30        |\n",
            "|    total_timesteps    | 2500      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -41.2     |\n",
            "|    explained_variance | 0         |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 499       |\n",
            "|    policy_loss        | 571       |\n",
            "|    reward             | -8.450254 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 284       |\n",
            "-------------------------------------\n",
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 81         |\n",
            "|    iterations         | 600        |\n",
            "|    time_elapsed       | 36         |\n",
            "|    total_timesteps    | 3000       |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.2      |\n",
            "|    explained_variance | 1.19e-07   |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 599        |\n",
            "|    policy_loss        | 112        |\n",
            "|    reward             | -0.5293981 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 8.02       |\n",
            "--------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 82        |\n",
            "|    iterations         | 700       |\n",
            "|    time_elapsed       | 42        |\n",
            "|    total_timesteps    | 3500      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -41.2     |\n",
            "|    explained_variance | -0.0134   |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 699       |\n",
            "|    policy_loss        | 60.6      |\n",
            "|    reward             | -3.293049 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 3.7       |\n",
            "-------------------------------------\n",
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 82         |\n",
            "|    iterations         | 800        |\n",
            "|    time_elapsed       | 48         |\n",
            "|    total_timesteps    | 4000       |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.2      |\n",
            "|    explained_variance | 0          |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 799        |\n",
            "|    policy_loss        | -14.9      |\n",
            "|    reward             | -2.4913642 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 0.629      |\n",
            "--------------------------------------\n",
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 83         |\n",
            "|    iterations         | 900        |\n",
            "|    time_elapsed       | 54         |\n",
            "|    total_timesteps    | 4500       |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.2      |\n",
            "|    explained_variance | 0          |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 899        |\n",
            "|    policy_loss        | 228        |\n",
            "|    reward             | -1.1507895 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 33.2       |\n",
            "--------------------------------------\n",
            "--------------------------------------\n",
            "| time/                 |            |\n",
            "|    fps                | 83         |\n",
            "|    iterations         | 1000       |\n",
            "|    time_elapsed       | 59         |\n",
            "|    total_timesteps    | 5000       |\n",
            "| train/                |            |\n",
            "|    entropy_loss       | -41.2      |\n",
            "|    explained_variance | -1.19e-07  |\n",
            "|    learning_rate      | 0.0007     |\n",
            "|    n_updates          | 999        |\n",
            "|    policy_loss        | 73.6       |\n",
            "|    reward             | -1.4470645 |\n",
            "|    std                | 1          |\n",
            "|    value_loss         | 4.06       |\n",
            "--------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 83        |\n",
            "|    iterations         | 1100      |\n",
            "|    time_elapsed       | 65        |\n",
            "|    total_timesteps    | 5500      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -41.2     |\n",
            "|    explained_variance | 1.19e-07  |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 1099      |\n",
            "|    policy_loss        | -50.7     |\n",
            "|    reward             | 0.6880832 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 9.48      |\n",
            "-------------------------------------\n"
          ]
        },
        {
          "output_type": "error",
          "ename": "KeyboardInterrupt",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-22-10fe1e0717a3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m trained_a2c = agent.train_model(model=model_a2c, \n\u001b[1;32m      2\u001b[0m                              \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'a2c'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m                              total_timesteps=50000)\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/finrl/drl_agents/stablebaselines3/models.py\u001b[0m in \u001b[0;36mtrain_model\u001b[0;34m(self, model, tb_log_name, total_timesteps)\u001b[0m\n\u001b[1;32m    103\u001b[0m             \u001b[0mtotal_timesteps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtotal_timesteps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    104\u001b[0m             \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtb_log_name\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 105\u001b[0;31m             \u001b[0mcallback\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTensorboardCallback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    106\u001b[0m         )\n\u001b[1;32m    107\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/a2c/a2c.py\u001b[0m in \u001b[0;36mlearn\u001b[0;34m(self, total_timesteps, callback, log_interval, eval_env, eval_freq, n_eval_episodes, tb_log_name, eval_log_path, reset_num_timesteps)\u001b[0m\n\u001b[1;32m    199\u001b[0m             \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtb_log_name\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    200\u001b[0m             \u001b[0meval_log_path\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0meval_log_path\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 201\u001b[0;31m             \u001b[0mreset_num_timesteps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreset_num_timesteps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    202\u001b[0m         )\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/common/on_policy_algorithm.py\u001b[0m in \u001b[0;36mlearn\u001b[0;34m(self, total_timesteps, callback, log_interval, eval_env, eval_freq, n_eval_episodes, tb_log_name, eval_log_path, reset_num_timesteps)\u001b[0m\n\u001b[1;32m    235\u001b[0m         \u001b[0;32mwhile\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnum_timesteps\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0mtotal_timesteps\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 237\u001b[0;31m             \u001b[0mcontinue_training\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcollect_rollouts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0menv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcallback\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrollout_buffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_rollout_steps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_steps\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    238\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    239\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mcontinue_training\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/common/on_policy_algorithm.py\u001b[0m in \u001b[0;36mcollect_rollouts\u001b[0;34m(self, env, callback, rollout_buffer, n_rollout_steps)\u001b[0m\n\u001b[1;32m    176\u001b[0m                 \u001b[0mclipped_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maction_space\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maction_space\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhigh\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    177\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 178\u001b[0;31m             \u001b[0mnew_obs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrewards\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdones\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minfos\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0menv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclipped_actions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    179\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    180\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnum_timesteps\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0menv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnum_envs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/common/vec_env/base_vec_env.py\u001b[0m in \u001b[0;36mstep\u001b[0;34m(self, actions)\u001b[0m\n\u001b[1;32m    160\u001b[0m         \"\"\"\n\u001b[1;32m    161\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep_async\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 162\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep_wait\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    163\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    164\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mget_images\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mSequence\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/common/vec_env/dummy_vec_env.py\u001b[0m in \u001b[0;36mstep_wait\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m     42\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0menv_idx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnum_envs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     43\u001b[0m             obs, self.buf_rews[env_idx], self.buf_dones[env_idx], self.buf_infos[env_idx] = self.envs[env_idx].step(\n\u001b[0;32m---> 44\u001b[0;31m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0menv_idx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     45\u001b[0m             )\n\u001b[1;32m     46\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuf_dones\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0menv_idx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/finrl/finrl_meta/env_stock_trading/env_stocktrading.py\u001b[0m in \u001b[0;36mstep\u001b[0;34m(self, actions)\u001b[0m\n\u001b[1;32m    187\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    188\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 189\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mterminal\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mday\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    190\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mterminal\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    191\u001b[0m             \u001b[0;31m# print(f\"Episode: {self.episode}\")\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36munique\u001b[0;34m(self, level)\u001b[0m\n\u001b[1;32m   2239\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mlevel\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2240\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_index_level\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlevel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2241\u001b[0;31m         \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2242\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_shallow_copy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   2243\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/pandas/core/base.py\u001b[0m in \u001b[0;36munique\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1263\u001b[0m                     \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1264\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1265\u001b[0;31m             \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0munique1d\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1266\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1267\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/pandas/core/algorithms.py\u001b[0m in \u001b[0;36munique\u001b[0;34m(values)\u001b[0m\n\u001b[1;32m    397\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    398\u001b[0m     \u001b[0mtable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mhtable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 399\u001b[0;31m     \u001b[0muniques\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtable\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munique\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    400\u001b[0m     \u001b[0muniques\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_reconstruct_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muniques\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moriginal\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moriginal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    401\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0muniques\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
          ]
        }
      ],
      "source": [
        "trained_a2c = agent.train_model(model=model_a2c, \n",
        "                             tb_log_name='a2c',\n",
        "                             total_timesteps=50000)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MRiOtrywfAo1"
      },
      "source": [
        "### Model 2: DDPG"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "M2YadjfnLwgt"
      },
      "outputs": [],
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "model_ddpg = agent.get_model(\"ddpg\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "tCDa78rqfO_a",
        "jupyter": {
          "outputs_hidden": true
        }
      },
      "outputs": [],
      "source": [
        "trained_ddpg = agent.train_model(model=model_ddpg, \n",
        "                             tb_log_name='ddpg',\n",
        "                             total_timesteps=50000)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_gDkU-j-fCmZ"
      },
      "source": [
        "### Model 3: PPO"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "y5D5PFUhMzSV"
      },
      "outputs": [],
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "PPO_PARAMS = {\n",
        "    \"n_steps\": 2048,\n",
        "    \"ent_coef\": 0.01,\n",
        "    \"learning_rate\": 0.00025,\n",
        "    \"batch_size\": 128,\n",
        "}\n",
        "model_ppo = agent.get_model(\"ppo\",model_kwargs = PPO_PARAMS)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Gt8eIQKYM4G3",
        "jupyter": {
          "outputs_hidden": true
        }
      },
      "outputs": [],
      "source": [
        "trained_ppo = agent.train_model(model=model_ppo, \n",
        "                             tb_log_name='ppo',\n",
        "                             total_timesteps=50000)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3Zpv4S0-fDBv"
      },
      "source": [
        "### Model 4: TD3"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "JSAHhV4Xc-bh"
      },
      "outputs": [],
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "TD3_PARAMS = {\"batch_size\": 100, \n",
        "              \"buffer_size\": 1000000, \n",
        "              \"learning_rate\": 0.001}\n",
        "\n",
        "model_td3 = agent.get_model(\"td3\",model_kwargs = TD3_PARAMS)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OSRxNYAxdKpU"
      },
      "outputs": [],
      "source": [
        "trained_td3 = agent.train_model(model=model_td3, \n",
        "                             tb_log_name='td3',\n",
        "                             total_timesteps=30000)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Dr49PotrfG01"
      },
      "source": [
        "### Model 5: SAC"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xwOhVjqRkCdM"
      },
      "outputs": [],
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "SAC_PARAMS = {\n",
        "    \"batch_size\": 128,\n",
        "    \"buffer_size\": 1000000,\n",
        "    \"learning_rate\": 0.0001,\n",
        "    \"learning_starts\": 100,\n",
        "    \"ent_coef\": \"auto_0.1\",\n",
        "}\n",
        "\n",
        "model_sac = agent.get_model(\"sac\",model_kwargs = SAC_PARAMS)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "K8RSdKCckJyH"
      },
      "outputs": [],
      "source": [
        "trained_sac = agent.train_model(model=model_sac, \n",
        "                             tb_log_name='sac',\n",
        "                             total_timesteps=60000)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f2wZgkQXh1jE"
      },
      "source": [
        "## Trading\n",
        "Assume that we have $1,000,000 initial capital at 2020-07-01. We use the DDPG model to trade Dow jones 30 stocks."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bEv5KGC8h1jE"
      },
      "source": [
        "### Set turbulence threshold\n",
        "Set the turbulence threshold to be greater than the maximum of insample turbulence data, if current turbulence index is greater than the threshold, then we assume that the current market is volatile"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "efwBi84ch1jE"
      },
      "outputs": [],
      "source": [
        "data_risk_indicator = processed_full[(processed_full.date<'2020-07-01') & (processed_full.date>='2009-01-01')]\n",
        "insample_risk_indicator = data_risk_indicator.drop_duplicates(subset=['date'])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "VHZMBpSqh1jG"
      },
      "outputs": [],
      "source": [
        "insample_risk_indicator.vix.describe()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "BDkszkMloRWT"
      },
      "outputs": [],
      "source": [
        "insample_risk_indicator.vix.quantile(0.996)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "AL7hs7svnNWT"
      },
      "outputs": [],
      "source": [
        "insample_risk_indicator.turbulence.describe()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "N78hfHckoqJ9"
      },
      "outputs": [],
      "source": [
        "insample_risk_indicator.turbulence.quantile(0.996)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U5mmgQF_h1jQ"
      },
      "source": [
        "### Trade\n",
        "\n",
        "DRL model needs to update periodically in order to take full advantage of the data, ideally we need to retrain our model yearly, quarterly, or monthly. We also need to tune the parameters along the way, in this notebook I only use the in-sample data from 2009-01 to 2020-07 to tune the parameters once, so there is some alpha decay here as the length of trade date extends. \n",
        "\n",
        "Numerous hyperparameters – e.g. the learning rate, the total number of samples to train on – influence the learning process and are usually determined by testing some variations."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cIqoV0GSI52v"
      },
      "outputs": [],
      "source": [
        "#trade = data_split(processed_full, '2020-07-01','2021-10-31')\n",
        "e_trade_gym = StockTradingEnv(df = trade, turbulence_threshold = 70,risk_indicator_col='vix', **env_kwargs)\n",
        "# env_trade, obs_trade = e_trade_gym.get_sb_env()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "W_XNgGsBMeVw"
      },
      "outputs": [],
      "source": [
        "trade.head()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "eLOnL5eYh1jR"
      },
      "outputs": [],
      "source": [
        "df_account_value, df_actions = DRLAgent.DRL_prediction(\n",
        "    model=trained_sac, \n",
        "    environment = e_trade_gym)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ERxw3KqLkcP4"
      },
      "outputs": [],
      "source": [
        "df_account_value.shape"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "2yRkNguY5yvp"
      },
      "outputs": [],
      "source": [
        "df_account_value.tail()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "nFlK5hNbWVFk"
      },
      "outputs": [],
      "source": [
        "df_actions.head()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "W6vvNSC6h1jZ"
      },
      "source": [
        "<a id='6'></a>\n",
        "# Part 7: Backtest Our Strategy\n",
        "Backtesting plays a key role in evaluating the performance of a trading strategy. Automated backtesting tool is preferred because it reduces the human error. We usually use the Quantopian pyfolio package to backtest our trading strategies. It is easy to use and consists of various individual plots that provide a comprehensive image of the performance of a trading strategy."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Lr2zX7ZxNyFQ"
      },
      "source": [
        "<a id='6.1'></a>\n",
        "## 7.1 BackTestStats\n",
        "pass in df_account_value, this information is stored in env class\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Nzkr9yv-AdV_"
      },
      "outputs": [],
      "source": [
        "print(\"==============Get Backtest Results===========\")\n",
        "now = datetime.datetime.now().strftime('%Y%m%d-%Hh%M')\n",
        "\n",
        "perf_stats_all = backtest_stats(account_value=df_account_value)\n",
        "perf_stats_all = pd.DataFrame(perf_stats_all)\n",
        "perf_stats_all.to_csv(\"./\"+config.RESULTS_DIR+\"/perf_stats_all_\"+now+'.csv')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QkV-LB66iwhD"
      },
      "outputs": [],
      "source": [
        "#baseline stats\n",
        "print(\"==============Get Baseline Stats===========\")\n",
        "baseline_df = get_baseline(\n",
        "        ticker=\"^DJI\", \n",
        "        start = df_account_value.loc[0,'date'],\n",
        "        end = df_account_value.loc[len(df_account_value)-1,'date'])\n",
        "\n",
        "stats = backtest_stats(baseline_df, value_col_name = 'close')\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qg1kvfemrrQH"
      },
      "outputs": [],
      "source": [
        "df_account_value.loc[0,'date']"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "tt1bzL5OrsTa"
      },
      "outputs": [],
      "source": [
        "df_account_value.loc[len(df_account_value)-1,'date']"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9U6Suru3h1jc"
      },
      "source": [
        "<a id='6.2'></a>\n",
        "## 7.2 BackTestPlot"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "lKRGftSS7pNM"
      },
      "outputs": [],
      "source": [
        "print(\"==============Compare to DJIA===========\")\n",
        "%matplotlib inline\n",
        "# S&P 500: ^GSPC\n",
        "# Dow Jones Index: ^DJI\n",
        "# NASDAQ 100: ^NDX\n",
        "backtest_plot(df_account_value, \n",
        "             baseline_ticker = '^DJI', \n",
        "             baseline_start = df_account_value.loc[0,'date'],\n",
        "             baseline_end = df_account_value.loc[len(df_account_value)-1,'date'])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "BzBaE63H3RLc"
      },
      "outputs": [],
      "source": [
        ""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ZYeOjax-7H_5"
      },
      "outputs": [],
      "source": [
        ""
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "Uy5_PTmOh1hj",
        "_gDkU-j-fCmZ",
        "3Zpv4S0-fDBv"
      ],
      "name": "FinRL_StockTrading_NeurIPS_2018.ipynb",
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.5"
    },
    "pycharm": {
      "stem_cell": {
        "cell_type": "raw",
        "metadata": {
          "collapsed": false
        },
        "source": []
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}